package com.sztx.pay.center.dataaccess.dao.redis.impl;

import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.stereotype.Repository;

import com.sztx.pay.center.dataaccess.dao.redis.LockRedisDAO;
import com.sztx.se.dataaccess.redis.callback.RedisCallback;
import com.sztx.se.dataaccess.redis.impl.BaseRedisDAOImpl;

/**
 * 
 * @author zhihongp
 *
 */
@Repository("lockRedisDAO")
public class LockRedisDAOImpl extends BaseRedisDAOImpl implements LockRedisDAO {
	public static String PREFIX_LOCK = "paycenter:lock:";
	
	public static final long EXPIRE_TIME_MQ = 300l;   //5分钟超时
	public static final long EXPIRE_TIME_ORDER = 600l;   //10分钟超时

	@Override
	public boolean lockMqMessage(final String messageId) {		
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + "mq:" + messageId;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				boolean flag = connection.setNX(key, serialize(key));
				if (flag) {
					connection.expire(key, EXPIRE_TIME_MQ);
				}
				return flag;
			}
		});	
	}

	@Override
	public boolean lockOrder(final String orderId, final String orderStatus) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + "order:" + orderId;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				boolean flag = connection.setNX(key, serialize(orderStatus));
				if (flag) {
					connection.expire(key, EXPIRE_TIME_ORDER);
				}
				return flag;
			}
		});
	}

	@Override
	public boolean unLockOrder(String orderId, String orderStatus) {
		
		
		return false;
	}



	@Override
	public String getLockOrderStatus(final String orderId) {
		
		return redisTemplate.execute(new RedisCallback<String>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + "order:" + orderId;
			}
			
			@Override
			public String doInRedis(RedisConnection connection, byte[] key) {				
				byte[] data = connection.get(key);
				
				if (data != null && data.length > 0) {			
					return deserialize(String.class, data);
				}
				return null;
			}
		});		
	}

	@Override
	public boolean lockOrder(final String orderId, final String orderStatus, final String prefix) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + prefix + ":order:" + orderId;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				boolean flag = connection.setNX(key, serialize(orderStatus));
				if (flag) {
					connection.expire(key, EXPIRE_TIME_ORDER);
				}
				return flag;
			}
		});
	}

	@Override
	public boolean lockOrder(final String orderId, final String orderStatus, final String prefix, final long expireTime) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + prefix + ":order:" + orderId;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				boolean flag = connection.setNX(key, serialize(orderStatus));
				if (flag) {
					connection.expire(key, expireTime);
				}
				return flag;
			}
		});
	}
	
	@Override
	public boolean unlockOrder(final String orderId, final String orderStatus, final String prefix) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + prefix + ":order:" + orderId;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				connection.del(key);
				return true;
			}
		});
	}

	@Override
	public boolean lockSettleOrder(final String settleDay, final long expireTime) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + ":settleDay:" + settleDay;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				boolean flag = connection.setNX(key, serialize(settleDay));
				if (flag) {
					connection.expire(key, expireTime);
				}
				return flag;
			}
		});
	}

	@Override
	public boolean unLockSettleOrder(final String settleDay) {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public String getKey() {
				return PREFIX_LOCK + ":settleDay:" + settleDay;
			}

			@Override
			public Boolean doInRedis(RedisConnection connection, byte[] key) {
				connection.del(key);
				return true;
			}
		});
	}

}
